package com.supermap.wzhy.module.user.service;

import com.supermap.wzhy.util.tree.DHTMLXTree;
import com.supermap.wzhy.util.tree.DHTMLXTreeFactory;
import com.supermap.wzhy.entity.*;
import com.supermap.wzhy.module.data.dao.MicroIdenmetaDao;
import com.supermap.wzhy.module.data.dao.MicroTablemetaDao;
import com.supermap.wzhy.module.user.dao.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by W.Hao on 14-2-27.
 * 用户和角色权限管理
 */
@Service
public class PowerService {

    @Autowired
    PowerDao powerDao;
    @Autowired
    MicroTablemetaDao microTablemetaDao ;
    @Autowired
    MicroIdenmetaDao microIdenmetaDao;
    @Autowired
    private PowerCatalogsDao powerCatalogsDao;
    @Autowired
    UserRoleDao userRoleDao ;
    @Autowired
    DataPowerService dataPowerService ;
    @Autowired
    UserDao userDao;


    public TUserpower create(TUserpower entity) {
        return powerDao.saveAndFlush(entity);
    }

    public boolean delete(int id) {
        TUserpower userpower = powerDao.getOne(id);
        if (userpower != null) {
            powerDao.delete(userpower);
            return true;
        } else
            return false;
    }

    public boolean update(int id, TUserpower entity) {
        if (powerDao.getOne(id) != null) {
            if (powerDao.save(entity) != null) {
                return true;
            } else
                return false;
        } else return false;
    }

    public TUserpower one(TUserpower entity) {
        return powerDao.findOne(entity.getPowerid());
    }


    public TUserpower getOne(int id) {
        return powerDao.findOne(id);
    }

    /**
     * 通过PowerCatalog找Power
     *
     * @param id
     * @return
     */
    public List<TUserpower> findPowersByCatalog(int id) {
        return powerDao.findPowerByCatalog(id);
    }

    public List<TUserpower> findUserpowerListByRoleid(int id){ return powerDao.findUserpowerListByRoleid(id); }


    public Page<TUserpower> findAll(PageRequest pageRequest) {
        return powerDao.findAll(pageRequest);
    }


    /**
     * 获取权限分类树
     * @return
     */
    public Map<String,Object> getRootPowers(){
        Map<String,Object> re = new HashMap<>();

        List<TUserpowercatalog> powerCatalogs = powerCatalogsDao.findAll();
        //系统权限树
        DHTMLXTree sysPowerTree = new DHTMLXTree("sys","系统权限列表")
                .noCheckbox().open();
        sysPowerTree.setUserData("parid","");     //分类
        sysPowerTree.setUserData("pcataid","");

        for(TUserpowercatalog powercatalog:powerCatalogs){
            DHTMLXTree node = new DHTMLXTree(powercatalog.getPcataid()+"_sys"
                    ,powercatalog.getName()).noCheckbox();

            node.setUserData("parid","root");     //分类
            node.setUserData("pcataid",powercatalog.getPcataid()+"");

            //判断判断权限分类下是否有数据
            if(checkIsExistPowerDataBypcataid(powercatalog.getPcataid(),0))
                node.add(new DHTMLXTree().loading());

            sysPowerTree.add(node);
        }
        re.put("sys", DHTMLXTreeFactory.toTree(sysPowerTree));

        return re;
    }

    /**
     * 获取权限分类树下第一级
     * @return
     */
    public Map<String,Object> getRootPowerTreeLeafByPcataid(int pcataid){
        Map<String,Object> re = new HashMap<>();

        DHTMLXTree sysPowerTree = null;

        TUserpowercatalog tUserpowercatalog= powerCatalogsDao.getOne(pcataid);
        if(tUserpowercatalog != null){
            sysPowerTree = new DHTMLXTree(tUserpowercatalog.getPcataid()+"_sys"
                    ,tUserpowercatalog.getName());
            sysPowerTree.setUserData("parid","root");     //分类
            sysPowerTree.setUserData("pcataid",tUserpowercatalog.getPcataid()+"");

            List<TUserpower> list = powerDao.findByParid(pcataid, 0); //指定分类下的第一级权限

            if(list != null && list.size() > 0){
                for(TUserpower tUserpower:list){
                    DHTMLXTree node = new DHTMLXTree(tUserpower.getPowerid()+""
                            ,tUserpower.getPowerName()).noCheckbox();
                    node.setUserData("parid",tUserpower.getParid()+"");                 //存储当前节点的父节点
                    node.setUserData("pcataid",tUserpower.getTUserpowercatalog().getPcataid()+"");   //存储当前所属权限分类


                    //判断指定pwerid下是否有子节点
                    if(checkIsExistChildenPowerDataByParid(tUserpower.getTUserpowercatalog().getPcataid(),
                            tUserpower.getPowerid())) {
                        node.add(new DHTMLXTree().loading());
                    }

                    sysPowerTree.add(node);
                }
            }

            re.put("sys",sysPowerTree.toString());
        }
        return re;
    }

    /**
     *
     *
     * @param powerid
     * @return
     */
    public Map<String,Object> getPowerTreeLeafBypowerid(int powerid){
        Map<String,Object> re = new HashMap<>();

        DHTMLXTree sysPowerTree = null;

         TUserpower tUserpower = powerDao.getOne(powerid);
        if(tUserpower != null){
            sysPowerTree = new DHTMLXTree(tUserpower.getPowerid()+""
                    ,tUserpower.getPowerName());
            sysPowerTree.setUserData("parid",tUserpower.getParid()+"");     //分类
            sysPowerTree.setUserData("pcataid",tUserpower.getTUserpowercatalog().getPcataid()+"");

            List<TUserpower> list = powerDao.findByParid(tUserpower.getTUserpowercatalog().getPcataid(),
                    tUserpower.getPowerid()); //指定pwerid下的子节点
            if(list != null && list.size() > 0){
                for(TUserpower tUserpower1:list){
                    DHTMLXTree node = new DHTMLXTree(tUserpower1.getPowerid()+""
                            ,tUserpower1.getPowerName()).noCheckbox();

                    node.setUserData("parid",tUserpower1.getParid()+"");                 //存储当前节点的父节点
                    node.setUserData("pcataid",tUserpower1.getTUserpowercatalog().getPcataid()+"");   //存储当前所属权限分类

                    //判断指定pwerid下是否有子节点
                    if(checkIsExistChildenPowerDataByParid(tUserpower1.getTUserpowercatalog().getPcataid(),
                            tUserpower1.getPowerid())) {
                        node.add(new DHTMLXTree().loading());
                    }

                    sysPowerTree.add(node);
                }
            }

            re.put("sys",sysPowerTree.toString());
        }
        return re;
    }

    /**
     * 判断权限分类下是否有数据
     *
     * @param pcataid
     *
     * @return
     */
    private boolean checkIsExistPowerDataBypcataid(int pcataid,int parid){
        boolean re = false;

        List<TUserpower> list = powerDao.findByParid(pcataid, parid); //指定分类下的第一级权限
        if(list != null && list.size() > 0){
            re = true;  //有数据
        }

        return re;
    }

    /**
     * 判断指定pwerid下是否有子节点
     *
     * @param parid
     *          父节点id(指定pwerid作为父节点)
     *
     * @return
     */
    private boolean checkIsExistChildenPowerDataByParid(int pcataid,int parid){
        boolean re = false;

        List<TUserpower> list = powerDao.findByParid(pcataid, parid); //指定pwerid下是否有子节点
        if(list != null && list.size() > 0){
            re = true;  //有数据
        }

        return re;
    }

    /**
     * 获取指定权限分类和父节点的权限（即父节点的子节点）
     * @param pcataid
     * @param parid
     * @return
     */
    public List<TUserpower> getPowerBypcataIdAndParid(int pcataid,int parid){
        return powerDao.findByParid(pcataid, parid); //指定pwerid下是否有子节点
    }

    /**
     *
     * 删除指定节点和其所有字节点的权限
     *
     * 说明：（此操作会删除该节点及其所有子节点）
     * 按照ID删除（不（强制）关联删除）
     * 删除的时候若该权限及其所有子权限都不被用户或者角色使用，才可以删除
     *
     * @param powerid
     *          指定节点的id
     * @return
     */
    public Map<String,Object> deletePowerAndallChildrenItemsForNoForce(int powerid){
        Map<String,Object> re = null;

        boolean isCandelete = true; //默认可以删除

        TUserpower tUserpower = getOne(powerid);    //取得要删除的权限信息
        if(tUserpower != null){

            //判断该权限是否被角色使用
            re = checkPowerIsUsedByAnyRole(tUserpower);
            if(re != null){  //该角色已被角色使用
                isCandelete = false;    //标记不可删除
            }else{
                //判断该权限是否被用户使用
                re = checkPowerIsUsedByAnyUser(tUserpower);
                if(re != null){ //该角色已被用户使用
                    isCandelete = false;   //标记不可删除
                }
            }//end if(re != null) else


            if(isCandelete){
                //取得当前节点的所有子节点(递归)
                List<TUserpower> allChildren = getAllChildrenPoweridBypowerid(tUserpower.getTUserpowercatalog().getPcataid(),powerid);

                if(allChildren != null && allChildren.size() > 0){
                    for (TUserpower child : allChildren){
                        if(child == null)
                            continue;

                        //判断该权限是否被角色使用
                        re = checkPowerIsUsedByAnyRole(child);
                        if(re != null){  //该角色已被角色使用
                            isCandelete = false;    //标记不可删除
                            break;  //退出循环 for (TUserpower child : allChildren)
                        }else{
                            //判断该权限是否被用户使用
                            re = checkPowerIsUsedByAnyUser(child);
                            if(re != null){ //该角色已被用户使用
                                isCandelete = false;   //标记不可删除
                                break;  //退出循环 for (TUserpower child : allChildren)
                            }
                        }//end if(re != null) else
                    }
                }

                if(isCandelete){  //可以删除
                    re = new HashMap<String,Object>();  //初始化返回对象
                    re.put("status",true);

                    if(allChildren != null && allChildren.size() > 0){
                        for (TUserpower child : allChildren){
                            if(child == null)
                                continue;
                            delete(child.getPowerid());   //移除子权限
                        }
                    }
                    delete(powerid);  //删除自己

                    re.put("msg","删除权限成功！");
                } //end if(isCandelete)
            }//end if(isCandelete)
        }else{
            re.put("status",true);
            re.put("msg","删除权限失败！该权限不存在！");
        }

        return re;
    }

    /**
     * 判断指定权限是否被角色使用
     *
     * @param tUserpower
     *              指定权限
     * @return 若返回null,代表没有被角色使用，否则被使用
     */
    public Map<String,Object> checkPowerIsUsedByAnyRole(TUserpower tUserpower){
        Map<String,Object> re = null;

        //获取指定权限下的所有用户角色,判断权限是否角色被使用
        List<TUserrole> userroleList = userRoleDao.findUserrolesBypowerid(tUserpower.getPowerid());
        if(userroleList != null && userroleList.size() > 0){
            re = new HashMap<String,Object>();

            //该权限已被角色使用，不可删除
            re.put("status",false);

            StringBuilder sb = new StringBuilder("权限["+tUserpower.getPowerName()+"]已被角色");
            for (int j=0,size2 = userroleList.size();j<size2;j++){
                TUserrole tUserrole = userroleList.get(j);
                if(tUserrole == null)
                    continue;
                if(j != 0){
                    sb.append("、");
                }
                sb.append("[").append(tUserrole.getRolename()).append("]");
                if(j > 2){
                    sb.append(" 等");
                    break;
                }
            } //end for (int j=0,size2 = userroleList.size();j<size2;j++)

            sb.append("使用，不可删除！");

            re.put("msg",sb.toString());
        }

        return re;
    }

    /**
     * 判断指定权限是否被用户使用
     *
     * @param tUserpower
     *              指定权限
     * @return 若返回null,代表没有被用户使用，否则被使用
     */
    public Map<String,Object> checkPowerIsUsedByAnyUser(TUserpower tUserpower){
        Map<String,Object> re = null;

        //2.获取指定权限下的所有用户,判断权限是否被用户使用
        List<TUsers> usersList = userDao.findUsersByPower(tUserpower.getPowerid());
        if(usersList != null && usersList.size() > 0) {
            re = new HashMap<String,Object>();

            //该权限已被用户使用，不可删除
            re.put("status", false);

            StringBuilder sb = new StringBuilder("权限["+tUserpower.getPowerName()+"]已被用户");
            for (int k=0,size3 = usersList.size();k<size3;k++){
                TUsers tUsers = usersList.get(k);
                if(tUsers == null)
                    continue;
                if(k != 0){
                    sb.append("、");
                }
                sb.append("[").append(tUsers.getUserCaption()).append("]");
                if(k > 2){
                    sb.append(" 等");
                    break;
                }
            } //end for (int k=0,size3 = usersList.size();k<size3;k++)

            sb.append("使用，不可删除！");

            re.put("msg",sb.toString());

        }//end if(usersList != null && usersList.size() > 0)

        return re;
    }


    /**
     * 获取指定权限下的所有子权限列表(递归)
     *
     * @param pcataid
     *
     * @param powerid
     * @return
     */
    public List<TUserpower> getAllChildrenPoweridBypowerid(int pcataid,int powerid){
        List<TUserpower> list = new ArrayList<TUserpower>();

        List<TUserpower> tUserpowers = getPowerBypcataIdAndParid(pcataid,powerid); //获取当前节点下的子节点
        if(tUserpowers != null && tUserpowers.size() > 0){
            for (TUserpower tUserpower : tUserpowers){
                if(tUserpower == null)
                    continue;
                list.add(tUserpower);   //添加节点

                int pcataid2 = tUserpower.getTUserpowercatalog().getPcataid();
                int powerid2 = tUserpower.getPowerid();
                List<TUserpower> tUserpowers2 = getAllChildrenPoweridBypowerid(pcataid2,powerid2); //递归
                if (tUserpowers2 != null && tUserpowers2.size() > 0){
                    for (TUserpower tUserpower2 : tUserpowers2){
                        if(tUserpower2 == null)
                            continue;
                        list.add(tUserpower2);   //添加节点
                    }
                }
            }
        }

        return list;
    }

}
